package test

import (
	"bufio"
	"fmt"
	"github.com/beherochuling/beesoft_api/app/helper/net"
	"io"
	"log"
	"net/http"
	"os"
	"os/exec"

	"github.com/gogf/gf/v2/net/ghttp"
)

var TestStream = &testStreamApi{}

type testStreamApi struct{}

func (receiver *testStreamApi) Stream(r *ghttp.Request) {
	ctx := r.Context()
	ch := make(chan struct{})

	rPipe, wPipe, err := os.Pipe()
	if err != nil {
		panic(err)
	}

	cmd := exec.CommandContext(ctx, "python", "-c", "exec(\"import sys\\nimport time\\nfor i in range(40): print(i);sys.stdout.flush();time.sleep(0.1)\")")
	cmd.Stdout = wPipe
	cmd.Stderr = wPipe
	if err := cmd.Start(); err != nil {
		panic(err)
	}

	go writeOutput(r, rPipe)

	go func(ch chan struct{}) {
		err := cmd.Wait()
		if err != nil {
			panic(err)
		}

		err = wPipe.Close()
		if err != nil {
			panic(err)
		}

		ch <- struct{}{}
	}(ch)

	select {
	case <-ch:
	case <-ctx.Done():
		err := ctx.Err()
		log.Printf("Client disconnected: %s\n", err)
	}
}

func writeOutput(r *ghttp.Request, input io.ReadCloser) {
	net.NewResponse(r).SetSse()

	writer := r.Response.Writer.RawWriter()
	flusher, ok := writer.(http.Flusher)
	if !ok {
		panic("")
	}

	in := bufio.NewScanner(input)
	for in.Scan() {
		data := in.Text()
		fmt.Println(data)

		_, err := fmt.Fprintf(writer, "data: %s\n", data)
		if err != nil {
			panic(err)
		}

		flusher.Flush()
	}

	err := input.Close()
	if err != nil {
		panic(err)
	}
}
